// STL
#include <vector>                 // std::vector<>
// this
#include "statsxx/statistics.hpp" // statistics::moment_p()


// DESC: Calculates the variance of x.
//
template<typename T>
inline double statistics::variance(
                                   const std::vector<T> &x
                                   )
{
    double sigma2;

    // NOTE: The following *could* call statistics::moment_p(), and apply a conversion (n/(n-1)).
    // NOTE: ... However, the following does a lesser number of overall calculations and no conversion.

    // TODO: NOTE: See the note at the top of statistics.hpp.

    double xmean = statistics::mean(x);

    double sum = 0.;

    for( auto &xi : x )
    {
        double xi_xmean = static_cast<double>(xi) - xmean;
        sum += ( xi_xmean*xi_xmean );
    }

    sigma2 = sum/(x.size() - 1);

    return sigma2;
}

template<typename T, typename N>
inline double statistics::variance(
                                   const T _T,
                                   const T _T2,
                                   const N _N
                                   )
{
    // NOTE: The following is the "Computational Formula":
    //
    return ( (static_cast<double>(_T2) - static_cast<double>(_T * _T) / static_cast<double>(_N)) / static_cast<double>(_N - 1) );
}
